package com.ruoyi.forum.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.forum.api.dto.CircleTopicListDTO;
import com.ruoyi.forum.api.dto.CircleTopicManageListDTO;
import com.ruoyi.forum.api.vo.*;
import com.ruoyi.forum.constant.CircleConst;
import com.ruoyi.forum.constant.TopicTopStatusEnum;
import com.ruoyi.forum.domain.CircleLabel;
import com.ruoyi.forum.domain.CircleTopic;
import com.ruoyi.forum.domain.CircleTopicReply;
import com.ruoyi.forum.domain.CircleTopicReport;
import com.ruoyi.forum.service.*;
import com.ruoyi.forum.utils.DateUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Tag(name = "论坛动态", description = "论坛动态管理接口")
@RequestMapping(value = "/circle")
@Validated
@RestController
public class CircleTopicController extends BaseController {

    @Autowired
    private DozerBeanMapper mapper;

    @Autowired
    private AuthServiceExt authServiceExt;


    @Autowired
    private CircleLabelService circleLabelService;

    @Autowired
    private CircleTopicService circleTopicService;

    @Autowired
    private CircleTopicReplyService circleTopicReplyService;

    @Autowired
    private CircleNoticeReadService circleNoticeReadService;

    @Autowired
    private CircleTopicReportService circleTopicReportService;

    @Autowired
    private CircleBlacklistService blacklistService;

    @Operation(summary = "发表动态", description = "发表动态")
    @Parameters({
            @Parameter(name = "uid", description = "用户id", required = true),
            @Parameter(name = "content", description = "内容"),
            @Parameter(name = "imgs", description = "图片id，以逗号隔开"),
            @Parameter(name = "labelId", description = "话题标签id", required = true)
    })
    @RequestMapping(value = "/topic/save", method = RequestMethod.POST)
    public AjaxResult saveTopic(@RequestParam(value = "uid") String uid,
                                @RequestParam(value = "content", required = false) String content,
                                @RequestParam(value = "imgs", required = false) String imgs,
                                @RequestParam(value = "labelId") String labelId) {

        try {
            blacklistService.checkLimit(uid);

            if (content == null && imgs == null) {
                return AjaxResult.error("对象信息不存在");
            }

            CircleLabel circleLabel = circleLabelService.selectById(labelId);
            if (circleLabel == null) {
                return AjaxResult.error("该板块未找到");
            }

            Map<String, Object> data = circleTopicService.addTopic(uid, content, imgs, circleLabel);

            return AjaxResult.success(data);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }

    }


    @Operation(summary = "删除动态（后台管理）", description = "删除动态（后台管理）")
    @Parameter(name = "id", description = "动态id", required = true)
    @RequestMapping(value = "/topic/delete", method = RequestMethod.POST)
    public AjaxResult deleteTopic(@RequestParam(value = "id") Long id) {
        CircleTopic circleTopic = circleTopicService.getById(id);
        if (circleTopic == null) {
            return AjaxResult.error("对象信息不存在");
        }
        circleTopic.setDelFlag(1);
        circleTopicService.update(circleTopic);
        return AjaxResult.success();
    }

    @Operation(summary = "获取所有人圈子动态列表", description = "获取所有人圈子动态列表")
    @GetMapping(value = "/topic/list")
    public AjaxResult listTopic(@Parameter(hidden = true) @ModelAttribute CircleTopicListDTO dto) {
        List<CircleTopic> topicList = new ArrayList<>();
        // 第一次查询所有置顶数据
        if (dto.getCreateTime() == null) {
            topicList.addAll(listTopTopic(dto));
        }
        // 当置顶数据不够条数时使用非置顶数据填充
        Integer rows = dto.getRows() - topicList.size();
        if (rows > 0) {
            topicList.addAll(listUnTopTopic(dto, rows));
        } else {
            // 默认有一条填充
            topicList.addAll(listUnTopTopic(dto, 1));
        }
        List<TopicItem> topicItemList = convertTopicItem(dto.getUid(), topicList);
        AjaxResult result = AjaxResult.success(topicItemList);
        return result;
    }

    /**
     * 获取置顶的帖子列表
     *
     * @param dto
     * @return
     */
    private List<CircleTopic> listTopTopic(CircleTopicListDTO dto) {
        // 使用 LambdaQueryWrapper 构造查询条件
        LambdaQueryWrapper<CircleTopic> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CircleTopic::getDelFlag, 0)
                .eq(CircleTopic::getTopStatus, TopicTopStatusEnum.TOP.value());

        if (StringUtils.isNotBlank(dto.getKeyword())) {
            wrapper.like(CircleTopic::getContent, StringEscapeUtils.unescapeHtml4(dto.getKeyword()));
        }

        if (StringUtils.isNotBlank(dto.getLableId())) {
            wrapper.eq(CircleTopic::getLableId, dto.getLableId());
        }

        // 设置排序条件
        wrapper.orderByDesc(CircleTopic::getTopStatus, CircleTopic::getTopTime);

        // 执行查询
        return circleTopicService.listTopTopic(wrapper);
    }

    /**
     * 获取非置顶的帖子列表
     *
     * @param dto
     * @param rows
     * @return
     */
    private List<CircleTopic> listUnTopTopic(CircleTopicListDTO dto, Integer rows) {
        // 使用 LambdaQueryWrapper 构造查询条件
        LambdaQueryWrapper<CircleTopic> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CircleTopic::getDelFlag, 0)
                .eq(CircleTopic::getTopStatus, TopicTopStatusEnum.UNTOP.value());

        if (dto.getCreateTime() != null) {
            wrapper.lt(CircleTopic::getCreateTime, dto.getCreateTime());
        }

        if (StringUtils.isNotBlank(dto.getKeyword())) {
            wrapper.like(CircleTopic::getContent, StringEscapeUtils.unescapeHtml4(dto.getKeyword()));
        }

        if (StringUtils.isNotBlank(dto.getLableId())) {
            wrapper.eq(CircleTopic::getLableId, dto.getLableId());
        }

        // 设置排序
        wrapper.orderByDesc(CircleTopic::getCreateTime);

        // 执行分页查询
        Page<CircleTopic> topicPage = new Page<>(1, rows);
        return circleTopicService.page(topicPage, wrapper).getRecords();

    }

    /**
     * 转换成TopicItem列表
     *
     * @param uid
     * @param topicList
     * @return
     */
    private List<TopicItem> convertTopicItem(String uid, List<CircleTopic> topicList) {
        List<TopicItem> topicItemList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(topicList)) {
            List<String> uidList = topicList.stream().map(CircleTopic::getUid).distinct().collect(Collectors.toList());
            List<Long> topicIds = topicList.stream().map(CircleTopic::getId).distinct().collect(Collectors.toList());

            Map<Long, Long> greatStatus = circleTopicReplyService.getGreatStatus(uid, topicIds);
            for (CircleTopic circleTopic : topicList) {
                TopicItem topicItem = mapper.map(circleTopic, TopicItem.class);
                topicItem.setLabel(circleTopic.getLableName());
                topicItem.setReplyItemList(listReplyItem(uidList, circleTopic));
                topicItem.setGreatStatus(StringUtils.isEmpty(uid) ? 0 : Optional.ofNullable(Optional.ofNullable(greatStatus).orElse(new HashMap<>()).get(circleTopic.getId())).orElse(0L).intValue());
                topicItemList.add(topicItem);
            }
            fillTopicUserInfo(uidList, topicItemList, false);
        }
        return topicItemList;
    }


    /**
     * 获取帖子评论列表
     *
     * @param uidSet
     * @param circleTopic
     * @return
     */
    private List<ReplyItem> listReplyItem(List<String> uidSet, CircleTopic circleTopic) {
        // 使用 LambdaQueryWrapper 构造查询条件
        LambdaQueryWrapper<CircleTopicReply> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CircleTopicReply::getTopicId, circleTopic.getId())
                .eq(CircleTopicReply::getReplyType, 1)
                .eq(CircleTopicReply::getDelFlag, 0);

// 设置排序
        wrapper.orderByDesc(CircleTopicReply::getTopFlag, CircleTopicReply::getCreateTime);

// 设置分页并执行查询
        Page<CircleTopicReply> p = new Page<>(1, 3);
        List<CircleTopicReply> topicReplyList = circleTopicReplyService.page(p, wrapper).getRecords();

        List<ReplyItem> replyItemList = new ArrayList<>();
        if (topicReplyList != null) {
            replyItemList = topicReplyList.stream().map(reply -> {
                uidSet.add(reply.getUid());
                if (StringUtils.isNotBlank(reply.getReplyTo())) {
                    uidSet.add(reply.getReplyTo());
                }
                return mapper.map(reply, ReplyItem.class);
            }).collect(Collectors.toList());
        }
        return replyItemList;
    }


    /**
     * 完善发帖用户资料
     *
     * @param uidSet
     * @param topicItemList
     */
    private void fillTopicUserInfo(List<String> uidSet, List<TopicItem> topicItemList, Boolean replyVip) {
        Map<String, UserDetail> userDetailMap = authServiceExt.getUserMapByUidList(uidSet);
        UserDetail user;
        if (CollectionUtils.isNotEmpty(topicItemList)) {
            for (TopicItem topicItem : topicItemList) {
                user = userDetailMap.get(topicItem.getUid());
                topicItem.setAvatar(user.getPortrait());
                topicItem.setName(user.getName());
                topicItem.setEmail(user.getEmail());
                for (ReplyItem replyItem : topicItem.getReplyItemList()) {
                    user = userDetailMap.get(replyItem.getUid());
                    replyItem.setAvatar(user.getPortrait());
                    replyItem.setName(user.getName());
                    if (StringUtils.isNotBlank(replyItem.getReplyTo())) {
                        user = userDetailMap.get(replyItem.getReplyTo());
                        if (user != null) {
                            replyItem.setReplyToName(user.getName());
                        }
                    }
                }
            }
        }
    }

    @Operation(summary = "查询动态列表", description = "查询动态列表")
    @GetMapping(value = "/topic/search")
    public TableDataInfo searchTopic(
            @RequestParam String keyword,
            @RequestParam(required = false, defaultValue = "1") Integer pageNo,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        // 使用 LambdaQueryWrapper 构造查询条件
        LambdaQueryWrapper<CircleTopic> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CircleTopic::getDelFlag, 0)
                .like(CircleTopic::getContent, StringEscapeUtils.unescapeHtml4(keyword));
// 设置排序和分页
        Page<CircleTopic> topicPage = new Page<>(pageNo, pageSize);
        topicPage.addOrder(new OrderItem("create_time", false)); // DESC排序
// 执行分页查询
        IPage<CircleTopic> page = circleTopicService.page(topicPage, wrapper);
        TableDataInfo result = new TableDataInfo();
        result.setTotal(page.getTotal());
        result.setRows(convertTopicItem(null, page.getRecords()));
        result.setCode(HttpStatus.SUCCESS);
        result.setMsg("查询成功");
        return result;
    }

    @Operation(summary = "获取动态列表(后台管理)", description = "获取动态列表(后台管理)")
    @GetMapping(value = "/topic/manage/list")
    public TableDataInfo listManageTopic(@Parameter(hidden = true) @ModelAttribute CircleTopicManageListDTO dto) {
        TableDataInfo topicPage = getManageTopicPage(dto);

        List<CircleTopicListVO> voList = new ArrayList<>();

        List<CircleTopic> rows = (List<CircleTopic>) topicPage.getRows();

        if (CollectionUtils.isNotEmpty(rows)) {
            voList = rows.stream().map(t -> {
                CircleTopicListVO vo = mapper.map(t, CircleTopicListVO.class);
                vo.setBlackFlag(blacklistService.getBlackedByUid(t.getUid()) != null ? 1 : 0);
                vo.setLabel(circleLabelService.selectById(t.getLableId()).getName());
                return vo;
            }).collect(Collectors.toList());

            Map<String, UserDetail> userMap = authServiceExt.getUserMapByUidList(voList.stream()
                    .map(CircleTopicListVO::getUid)
                    .distinct()
                    .collect(Collectors.toList()));
            voList.forEach(vo -> {
                if (userMap.containsKey(vo.getUid())) {
                    UserDetail user = userMap.get(vo.getUid());
                    vo.setPhone(user.getPhone());
                    vo.setName(user.getName());
                    vo.setEmail(user.getEmail());
                    vo.setAvatar(user.getPortrait());
                    vo.setRegTime(user.getT());
                }
            });
        }

        TableDataInfo result = new TableDataInfo();
        result.setTotal(topicPage.getTotal());
        result.setRows(voList);
        result.setCode(HttpStatus.SUCCESS);
        result.setMsg("查询成功");
        return result;
    }

    /**
     * 获取后台管理帖子分页数据
     *
     * @param dto
     * @return
     */
    private TableDataInfo getManageTopicPage(CircleTopicManageListDTO dto) {
        // 使用 LambdaQueryWrapper 构造查询条件
        LambdaQueryWrapper<CircleTopic> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(CircleTopic::getCreateTime);
        wrapper.eq(CircleTopic::getDelFlag, 0);
        if (StringUtils.isNotBlank(dto.getStartDate()) && StringUtils.isNotBlank(dto.getEndDate())) {
            long startTime = DateUtils.str2DateL(dto.getStartDate());
            long endTime = DateUtils.str2EDateL(dto.getEndDate());
            wrapper.ge(CircleTopic::getCreateTime, startTime)
                    .le(CircleTopic::getCreateTime, endTime);
        }

        if (StringUtils.isNotBlank(dto.getKeyword())) {
            wrapper.like(CircleTopic::getContent, StringEscapeUtils.unescapeHtml4(dto.getKeyword()));
        }
        if (StringUtils.isNotBlank(dto.getLableId())) {
            wrapper.eq(CircleTopic::getLableId, dto.getLableId());
        }
        if (dto.getReportFlag() != null) {
            wrapper.gt(CircleTopic::getReportNum, 0);
        }
        if (dto.getTopStatus() != null) {
            wrapper.eq(CircleTopic::getTopStatus, dto.getTopStatus());
        }

// 设置排序和分页
        Page<CircleTopic> topicPage = new Page<>(dto.getPageNum(), dto.getPageSize());
        topicPage.addOrder(
                new OrderItem("top_status", false),
                new OrderItem("top_time", false),
                new OrderItem("create_time", false)
        );

// 执行分页查询
        IPage<CircleTopic> page = circleTopicService.page(topicPage, wrapper);

        TableDataInfo result = new TableDataInfo();
        result.setTotal(page.getTotal());
        result.setRows(page.getRecords());
        result.setCode(HttpStatus.SUCCESS);
        result.setMsg("查询成功");
        return result;

    }


    @Operation(summary = "获取动态详情", description = "获取动态详情")
    @Parameter(name = "id", description = "动态id", required = true)
    @RequestMapping(value = "/topic/detail", method = RequestMethod.GET)
    public AjaxResult getTopicDetail(@RequestParam(value = "id") Long id, @RequestParam(value = "uid", required = false) String uid) {
        CircleTopic topic = circleTopicService.getById(id);
        if (topic.getDelFlag() != null && topic.getDelFlag() == 1) {
            return AjaxResult.error("该动态已被删除！");
        }
        UserDetail data = authServiceExt.getUserDetail(topic.getUid());
        TopicItem map = mapper.map(topic, TopicItem.class);
        map.setAvatar(data.getPortrait());
        map.setName(data.getName());
        CircleLabel circleLabel = circleLabelService.selectById(topic.getLableId());
        map.setLabel(circleLabel.getName());
        map.setPhone(data.getPhone());
        map.setEmail(data.getEmail());
        if (uid == null) {
            map.setGreatStatus(0);
        } else {
            map.setGreatStatus(circleTopicReplyService.getGreatStatus(uid, topic.getId()));
        }

        return AjaxResult.success(map);
    }


    @Operation(summary = "获取帖子举报记录列表", description = "获取帖子举报记录列表")
    @Parameters({
            @Parameter(name = "topicId", description = "帖子id", required = true),
            @Parameter(name = "pageNo", description = "页码", example = "1"),
            @Parameter(name = "pageSize", description = "条数", example = "10")
    })
    @GetMapping("/topic/{topicId}/report/list")
    public TableDataInfo listReport(@PathVariable Long topicId,
                                    @RequestParam(required = false, defaultValue = "1") Integer pageNo,
                                    @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        // 使用 LambdaQueryWrapper 构造查询条件
        LambdaQueryWrapper<CircleTopicReport> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CircleTopicReport::getTopicId, topicId);
// 设置排序和分页
        Page<CircleTopicReport> page = new Page<>(pageNo, pageSize);
        page.addOrder(new OrderItem("create_time", false)); // DESC排序

// 执行分页查询
        page = circleTopicReportService.page(page, wrapper);


        List<CircleTopicReportVO> reportVoList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            reportVoList = page.getRecords().stream()
                    .map(report -> mapper.map(report, CircleTopicReportVO.class))
                    .collect(Collectors.toList());

            Map<String, UserDetail> userMap = authServiceExt.getUserMapByUidList(reportVoList.stream()
                    .map(CircleTopicReportVO::getCreateBy)
                    .distinct()
                    .collect(Collectors.toList()));
            reportVoList.forEach(vo -> {
                if (userMap.containsKey(vo.getCreateBy())) {
                    UserDetail user = userMap.get(vo.getCreateBy());
                    vo.setPhone(user.getPhone());
                    vo.setEmail(user.getEmail());
                    vo.setUserName(user.getName());
                }
            });
        }

        TableDataInfo tableDataInfo = new TableDataInfo(reportVoList, page.getTotal());
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        return tableDataInfo;

    }

    @Operation(summary = "置顶/取消置顶帖子", description = "置顶/取消置顶帖子")
    @Parameters({
            @Parameter(name = "topicId", description = "帖子id", required = true),
            @Parameter(name = "topFlag", description = "置顶状态 0-取消置顶 1-置顶", required = true)
    })
    @PostMapping("/topic/{topicId}/top")
    public AjaxResult topTopic(@PathVariable Long topicId,
                               @RequestParam Integer topFlag) {
        CircleTopic topic = circleTopicService.getById(topicId);
        // 限制置顶数量
        if (TopicTopStatusEnum.TOP.value().equals(topFlag)) {
            Long num = circleTopicService.countTopByLabelId(topic.getLableId());
            if (num >= CircleConst.CIRCLE_TOP_NUM_LIMIT) {
                return AjaxResult.error("超出该板块置顶数量限制");
            }
        }
        circleTopicService.topTopic(topic, topFlag);
        return AjaxResult.success();
    }
}
